package kernel.stl.slicing;

import kernel.stl.LineSegment;
import kernel.stl.LineSegmentList;
import kernel.stl.PointXYZ;
import kernel.stl.STL;

//8,825

/**Representa uma fatia. Ela é formada por uma lista de segmentos de reta. 
 * @author George
 */
public class Slice {
    
    private LineSegmentList lineSegmentList;
    private STL stl;
   
    
    /**Construtor da classe Slice.
     * @param lineSegmentLine Lista de segmentos de reta que formam a fatia
     */    
    public Slice(LineSegmentList lineSegmentList) {
        this.lineSegmentList = lineSegmentList;
    }
    
    public void setSTL(STL stl) {
        this.stl = stl;
    }
    
    public STL getSTL() {
        return this.stl;
    }
    
    /**Faz a junção entre duas fatias. 
     * @param slice outra fatia a ser unida à fatia que chama este método
     */
    public void incorporate(Slice slice, double tolerance) {        
        this.lineSegmentList.addLineSegmentList(slice.getLineSegmentList(), tolerance);                
    }
    
    /**
     * @return Lista de segmentos de reta quem formam a fatia
     */   
    public LineSegmentList getLineSegmentList(){
        return this.lineSegmentList;
    }
    
    /**Cria uma string com a representação de todos os segmentos de reta da fatia.
     * 
     * @return
     */
    public String asString() {
        String s = "";
        
        for (int i = 0; i < this.getLineSegmentList().getLineSegmentCount(); i++) {
            LineSegment line = this.getLineSegmentList().getLineSegment(i);
            s = s + line.getPoint1().toPointXY().asString();
        }
        
        if (this.getLineSegmentList().getLineSegmentCount() > 0) {
            int count = this.getLineSegmentList().getLineSegmentCount();
            LineSegment line = this.getLineSegmentList().getLineSegment(count - 1);
            s = s + line.getPoint2().toPointXY().asString();
        } 
        else {
            s = "()";
        }
        
        return s;
    }
    
    private LineSegment newResizedLineSegment(LineSegment lineSegment, 
            int width, int height) {
        
        double stlWidth = this.stl.getSolid().getMaxX() - this.stl.getSolid().getMinX();
        double stlHeight = this.stl.getSolid().getMaxY() - this.stl.getSolid().getMinY();

        if (stlWidth > stlHeight) {
            stlHeight = stlWidth;
        } else {
            stlWidth = stlHeight;
        }
        double deltaX = lineSegment.getPoint1().getX() - this.stl.getSolid().getMinX();
        double deltaY = lineSegment.getPoint1().getY() - this.stl.getSolid().getMinY();

        int x1 = (int) Math.round(deltaX * width / stlWidth);
        int y1 = (int) Math.round(deltaY * height / stlHeight);

        deltaX = lineSegment.getPoint2().getX() - this.stl.getSolid().getMinX();
        deltaY = lineSegment.getPoint2().getY() - this.stl.getSolid().getMinY();

        int x2 = (int) Math.round(deltaX * width / stlWidth);
        int y2 = (int) Math.round(deltaY * height / stlHeight);
        
        PointXYZ p1 = new PointXYZ(x1, y1, lineSegment.getPoint1().getZ());
        PointXYZ p2 = new PointXYZ(x2, y2, lineSegment.getPoint2().getZ());
        
        return new LineSegment(p1, p2);
    }
    
    public Slice newResizedLayer(int width, int height) {   
        
        LineSegmentList list = new LineSegmentList();
        
        for (int i = 0; i < this.getLineSegmentList().getLineSegmentCount(); i++) {
            LineSegment lineSegment = newResizedLineSegment(
                    this.getLineSegmentList().getLineSegment(i), width, height);
            list.addLineSegment(lineSegment, 0);
        }
        
        return new Slice(list);
    }
    

}
